using System;
using System.Collections.Generic;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Net;
using Microsoft.Xna.Framework.Storage;
using System.Collections;
using NovodexWrapper;

namespace marbletrack
{
    class ContactReport : NxUserContactReport
    {
        public void onContactNotify(NxContactPair contactPair, uint events)
        {
            
            float force = contactPair.sumNormalForce.magnitude();
            //Put sound stuff here
            //the NxContactPairFlag enum can be used to check what event has occured eg.) if (events == (uint)NxContactPairFlag.NX_NOTIFY_ON_START_TOUCH)
            //the actors that can be access by contactPair.Actor0 and contactPair.Actor1 define many physics properties such as linear velocity
            //contactPair.Actor0/1.getGroup() can be called to get the physics group the actor belongs to which is either Ball.PHYSICS_GROUP or TrackPiece.PHYSICS_GROUP at the present time


            if (((contactPair.Actor0.getGroup() == Physics.TRACKPIECE_PHYSICS_GROUP && contactPair.Actor1.getGroup() == Physics.BALL_PHYSICS_GROUP) ||
                (contactPair.Actor0.getGroup() == Physics.BALL_PHYSICS_GROUP && contactPair.Actor1.getGroup() == Physics.TRACKPIECE_PHYSICS_GROUP)) &&
                events == (uint)NxContactPairFlag.NX_NOTIFY_ON_END_TOUCH)
            {
                NxActor ball = (Physics.BALL_PHYSICS_GROUP == contactPair.Actor0.getGroup()) ?
                    contactPair.Actor0 : contactPair.Actor1;

                if (ball.UserData == (IntPtr)1)
                {
                    
                }
            }


            if (((contactPair.Actor0.getGroup() == Physics.TRACKPIECE_PHYSICS_GROUP && contactPair.Actor1.getGroup() == Physics.BALL_PHYSICS_GROUP) ||
                (contactPair.Actor0.getGroup() == Physics.BALL_PHYSICS_GROUP && contactPair.Actor1.getGroup() == Physics.TRACKPIECE_PHYSICS_GROUP)) &&
                events == (uint)NxContactPairFlag.NX_NOTIFY_ON_START_TOUCH)
            {
                NxActor ball = (Physics.BALL_PHYSICS_GROUP == contactPair.Actor0.getGroup()) ?
                    contactPair.Actor0 : contactPair.Actor1;

                if (ball.UserData == (IntPtr)0)
                {
                    //Audio.soundBank.PlayCue("Marble rolling loop");
                    ball.UserData = (IntPtr)1;
                }

                Audio.trackHitCue = Audio.soundBank.GetCue("Marble hittin wood");
                Audio.trackHitCue.Apply3D(Audio.listener, Audio.emitter_T);
                Audio.trackHitVol = (float)(force / 1e13);
                Audio.trackHitCue.Play();
                //Audio.soundBank.PlayCue("Marble hittin wood");
            }

            //if two balls collide (only called on start touch)
            if (contactPair.Actor0.getGroup() == Physics.BALL_PHYSICS_GROUP && contactPair.Actor1.getGroup() == Physics.BALL_PHYSICS_GROUP)
            {
                Audio.marbleHitCue = Audio.soundBank.GetCue("marble hitting marble");
                Audio.trackHitCue.Apply3D(Audio.listener, Audio.emitter_M);
                Audio.marbleHitVol = (float)(force / 1e12);
                Audio.marbleHitCue.Play();
                //Audio.soundBank.PlayCue("marble hitting marble")
            }

            if (contactPair.Actor0.getGroup() == Physics.BALL_PHYSICS_GROUP && contactPair.Actor1.getGroup() == Physics.TRACKPIECE_PHYSICS_GROUP &&
                contactPair.Actor0.isDynamic())
            {
                Audio.marbleRolling = true;
            }
            else Audio.marbleRolling = false;
            Audio.update();

            //Boosts the ball if it hits an up slope
            if (contactPair.Actor0.getGroup() == Physics.BALL_PHYSICS_GROUP && contactPair.Actor1.getGroup() == Physics.BOOST_PHYSICS_GROUP)
            {
                Boost(contactPair.Actor0, contactPair.Actor1);
            }
            else if (contactPair.Actor0.getGroup() == Physics.BOOST_PHYSICS_GROUP && contactPair.Actor1.getGroup() == Physics.BALL_PHYSICS_GROUP)
            {
                Boost(contactPair.Actor1, contactPair.Actor0);
            }
        }

        //Check which direction the trackPiece is facing and Boost (spin) the ball in that direction
        private void Boost(NxActor ball, NxActor trackPiece)
        {
            if (MathConversion.NxMat33ToMatrix(trackPiece.GlobalOrientation) == TrackPiece.StraightOrientation)
            {
                ball.AngularVelocity += new NxVec3(5, 0, 0);
            }
            else if (MathConversion.NxMat33ToMatrix(trackPiece.GlobalOrientation) == TrackPiece.LeftOrientation)
            {
                ball.AngularVelocity += new NxVec3(0, 0, -5);
            }
            else if (MathConversion.NxMat33ToMatrix(trackPiece.GlobalOrientation) == TrackPiece.RightOrientation)
            {
                ball.AngularVelocity += new NxVec3(0, 0, 5);
            }
            else
            {
                ball.AngularVelocity += new NxVec3(-5, 0, 0);
            }
        }
    }
}
